#include<string>
#include<fstream>
#include<sstream>
#include<iostream>
#include<algorithm>
#include<iterator>
#include<vector>
#include<map>
#include<cstdlib>
#include<ctime>
#include<cmath>
#include <gsl/gsl_rng.h>
#include <gsl/gsl_randist.h>
#include "cmd.hpp"
#include "log.hpp"
#include "def.hpp"
#include "metamodel.hpp"

using namespace std;

int main(int argc, char* argv[]){
  /* Definitions */
  ModelFunc Model;

  srand(static_cast<unsigned int>(time(0))); // initialize random number generator
  PuzaDEF::Instance()->gBaseRand = gsl_rng_alloc(gsl_rng_mt19937);   /* specifying to use Mersenne twister MT-19937 as the uniform PRNG */
  PuzaDEF::Instance()->randSeed = rand();                    /* returns a non-negative integer */
  gsl_rng_set (PuzaDEF::Instance()->gBaseRand, PuzaDEF::Instance()->randSeed);    /* seed the PRNG */

  // first parse command line
  PuzaCMD::Instance()->parseCMD(argc, argv);

  /* start log */
  PuzaLogger::Instance()->Start();

  /* Get the model */
  Model =  getModel();

  (*Model)(); // run model

  /* end log */
  PuzaLogger::Instance()->End();

  return 0;
}
